package org.liang.job.core;

import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.liang.job.AutoJob;
import org.liang.job.common.JobConstant;
import org.liang.job.exceptions.JobException;
import org.liang.job.repository.TaskLogRepository;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.SchedulerException;
import org.springframework.context.ApplicationContext;

/**
 * 基础任务类
 * 
 * <pre>
 * 将任务参数、任务实现类添加到任务上.
 * </pre>
 * 
 * @author L.Yang
 * @version 1.0, 2015年9月22日
 */
public class BaseJob implements Job {

    @Override
    public void execute(JobExecutionContext context)
                    throws JobExecutionException {
        Map<String, Object> args = context.getJobDetail().getJobDataMap();
        String biz = getStringValue(JobConstant.JOB_BIZ_KEY, args);
        String title = getStringValue(JobConstant.JOB_TITLE_KEY, args);

        boolean status = true;
        String message = "";
        try {
            if (StringUtils.isEmpty(biz)) {
                throw new JobException("任务" + title + " 未能获取到任务业务逻辑执行类");
            }
            AutoJob job = (AutoJob) getBean(biz, context);
            job.execute(args);// 获取业务实现 并 将业务参数传入 进行调用
        } catch (Exception e) {
            status = false;
            message = e.getMessage();
        }

        log2DB(title, biz, args, status, message, context);
    }

    /**
     * 将任务执行情况记录的数据库.
     *
     * @param title
     *            任务标题
     * @param biz
     *            业务实现
     * @param args
     *            参数
     * @param status
     *            状态
     * @param message
     *            错误信息
     * @param context
     *            job上下文
     */
    private void log2DB(String title, String biz, Map<String, Object> args,
                        boolean status, String message, JobExecutionContext context) {
        TaskLogRepository taskLogRepository = (TaskLogRepository) getBean(
                        "taskLogRepository", context);
        taskLogRepository.save(title, context.getJobDetail().getKey()
            .getGroup(), biz, args, status, message);
    }

    /**
     * 获取string value,并将对应value移除.
     * 
     * @param key
     *            键值
     * @param args
     *            集合
     * @return 返回值
     */
    private String getStringValue(String key, Map<String, Object> args) {
        String rtn = args.get(key).toString();
        args.remove(key);
        return rtn;
    }
    /**
     * 根据bean名称和contex获取bean.
     * 
     * @param beanName
     *            bean名
     * @param context
     *            上下文
     * @return bean 实例
     */
    private static Object getBean(String beanName, JobExecutionContext context) {
        try {
            ApplicationContext applicationContext = (ApplicationContext) context
                .getScheduler().getContext().get("applicationContextKey");
            return applicationContext.getBean(beanName);
        } catch (SchedulerException e) {
            throw new RuntimeException("未找到调度任务上下文!", e);
        }
    }
}
